package router

import (
	"bufio"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/os/gsession"
	"github.com/gogf/gf/v2/text/gstr"
	"github.com/gogf/gf/v2/util/gconv"
	"miaoyu/internal/consts"

	"miaoyu/internal/model"
	modelAdmin "miaoyu/internal/model"
	"os"
)

// UrlBuild 路径生成函数
/**

路径 path  规则xx.xx.xxX.do
参数 param
前缀 prefix  xx.xx.xxX
*/

func MakeAdminMap() []modelAdmin.RouteMap {
	adminList := makeAdminRouteMap()
	//cmsList := makeCmsRouteMap()
	//actList := makePlayerRouteMap()
	//adminList = append(adminList, cmsList...)
	//adminList = append(adminList, actList...)
	for index, val := range adminList {
		if val.Style == "route" {
			key, pattern, method := UrlTranslate(&val)
			val.Pattern = pattern
			val.Method = method
			val.KeyName = key
			adminList[index] = val
		}
	}
	return adminList
}

func MakeTreeRouteMap() model.TreeNode {
	root := model.TreeNode{
		Data: nil,
		//Data: MakeOauthClientMap(),
		Children: []*model.TreeNode{
			//&model.TreeNode{
			//	Data:     MakeOauthClientMap(),
			//	Children: []*model.TreeNode{},
			//},
			&model.TreeNode{
				Data:     MakeAdminMap(),
				Children: []*model.TreeNode{},
			},
		},
	}

	return root
}

// registerTreesRoute 多叉树前序遍历
func registerTreeRoute(root *model.TreeNode, group *ghttp.RouterGroup) {

	if root == nil {
		return
	}
	// 遍历根节点
	if root.Data != nil {
		registerRoute(root.Data, group)
		storeRouteMapSimple(root.Data)
		WriteRouteMap(root.Data)
	}
	// 遍历子节点

	for _, child := range root.Children {
		group.Group("/", func(s *ghttp.RouterGroup) {

			registerTreeRoute(child, s)
		})
	}

	return
}

func UrlTranslate(imap *model.RouteMap) (string, string, string) {
	var (
		method = "GET"
		urlStr = ""
		prefix = "backend"
		suffix = "do"
		key    = ""
	)
	key = imap.KeyName
	if imap.Method != "" {
		method = imap.Method
	}
	if imap.Prefix != "" {
		prefix = imap.Prefix
	}
	if imap.Suffix != "" {
		suffix = imap.Suffix
	}

	if imap.NickRoute != "" {
		urlStr = "/" + imap.NickRoute
		pathSlice := gstr.SplitAndTrim(urlStr, "/")
		for index, data := range pathSlice {
			pathSlice[index] = gstr.CaseSnakeFirstUpper(data)
		}
		urlStr = "/" + gstr.Join(pathSlice, "/") + "." + suffix
	} else {
		pathSlice := gstr.SplitAndTrim(prefix+"/"+key, "/")
		for index, data := range pathSlice {
			pathSlice[index] = gstr.CaseSnakeFirstUpper(data)
		}
		urlStr = "/" + gstr.Join(pathSlice, "/") + "." + suffix
	}
	keySlice := gstr.SplitAndTrim(prefix+"/"+key, "/")
	key = gstr.Join(keySlice, "/")
	key = gstr.ToLower(key)
	method = gstr.ToLower(imap.Method)
	//pathSlice := strings.Split(path, "/")
	return key, urlStr, method
}
func storeRouteMapSimple(imap []model.RouteMap) {
	var simpleRouteMap []model.RouteMapSimple
	for _, val := range imap {
		if val.Style == "route" {
			simpleRouteMap = append(simpleRouteMap, model.RouteMapSimple{
				KeyName: val.KeyName,
				Pattern: val.Pattern,
				Method:  val.Method,
				IsLogin: val.IsLogin,
			})
		}
	}
	consts.RouteMap = append(consts.RouteMap, simpleRouteMap...)
}
func WriteRouteMap(imap []model.RouteMap) {

	file, err := os.OpenFile("route.map.txt", os.O_APPEND, 0)

	if err != nil {
		fmt.Println(err)
		return
	}
	defer file.Close()
	writer := bufio.NewWriter(file)
	for index, val := range imap {
		if val.Style == "route" {
			_, err = writer.WriteString("路由" + gconv.String(index) + "; desc= " + val.Desc + "\n")
			_, err = writer.WriteString("key= " + val.KeyName + "\n")
			_, err = writer.WriteString("route= " + val.Method + ":" + val.Pattern + "\n")
			if err != nil {
				fmt.Println(err)
			}
		}
	}
	writer.Flush()
	return
}

func registerRoute(maps []model.RouteMap, group *ghttp.RouterGroup) {

	for _, val := range maps {

		if val.Style == "route" {
			method := val.Method
			switch method {
			case "get":
				group.GET(val.Pattern, val.Handler)
			case "post":
				group.POST(val.Pattern, val.Handler)
			case "put":
				fmt.Println("put")
				group.PUT(val.Pattern, val.Handler)
			case "delete":
				group.DELETE(val.Pattern, val.Handler)
			default:
				group.ALL(val.Pattern, val.Handler)
			}
		} else if val.Style == "middleware" {
			group.Middleware(val.HandlerFunc)

		} else if val.Style == "hook" {
			group.Hook(val.Pattern, ghttp.HookName(val.KeyName), val.HandlerFunc)
		}
	}
}

func init() {
	var isRedis bool
	s := g.Server()
	config, confErr := g.Cfg().Get(gctx.New(), "session.redis")
	isRedis = gconv.Bool(config)
	if confErr != nil {
		panic("session缓存配置失败， cache config error")
	}
	if isRedis {
		s.SetSessionStorage(gsession.NewStorageRedis(g.Redis("session")))
	}
	//s.BindMiddlewareDefault(service.MiddlewareDefaultResponse)

	os.Remove("route.map.txt")
	os.Create("route.map.txt")
	s.Group("/", func(group *ghttp.RouterGroup) {
		maps := MakeTreeRouteMap()
		registerTreeRoute(&maps, group)
	})
	//s.Group("/", func(group *ghttp.RouterGroup) {
	//
	//	group.GET("/channel/{channel}.mhtml", cms.Channel.Index)
	//
	//})
}
